package com.clz.appdesign.audio_video;

import android.Manifest;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.SurfaceTexture;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.clz.appdesign.myapp.R;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * @author clz
 * @desc 音视频学习初级阶段 @link http://www.cnblogs.com/renhui/p/7452572.html
 */
public class AudioVideoPrimaryActivity extends AppCompatActivity {


    @BindView(R.id.root_container)
    LinearLayout mRootContainer;
    private boolean isRecord;
    private AudioRecord mAudioRecord;
    private FileOutputStream mFos;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_primary);
        ButterKnife.bind(this);
        //showImage(2);
    }

    /**
     * 实现Android录音的流程为：
     * <p>
     * 构造一个AudioRecord对象，其中需要的最小录音缓存buffer大小可以通过getMinBufferSize方法得到。如果buffer容量过小，将导致对象构造的失败。
     * 初始化一个buffer，该buffer大于等于AudioRecord对象用于写声音数据的buffer大小。
     * 开始录音
     * 创建一个数据流，一边从AudioRecord中读取声音数据到初始化的buffer，一边将buffer中数据导入数据流。
     * 关闭数据流
     * 停止录音
     */
    private void record() {
        ToastUtils.showShort("正在录音中...");
        LogUtils.iTag("record", "正在录音中...");
        mAudioRecord = null;
        //audioRecord能接受的最小的buffer大小
        int recordBufferSize = AudioRecord.getMinBufferSize(GlobalConfig.SAMPLE_RATE_INHZ, GlobalConfig.CHANNEL_CONFIG, GlobalConfig.AUDIO_FORMAT);
        mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, GlobalConfig.SAMPLE_RATE_INHZ, GlobalConfig.CHANNEL_CONFIG, GlobalConfig.AUDIO_FORMAT, recordBufferSize);
        byte[] data = new byte[recordBufferSize];
        mAudioRecord.startRecording();
        isRecord = true;
        mFos = null;
        String fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Record" + File.separator + "test.pcm";
        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.mkdirs();
        }
        if (file.exists()) {
            file.delete();
        }
        try {
            mFos = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (mFos != null) {
            if (isRecord) {
                final int read = mAudioRecord.read(data, 0, recordBufferSize);
                //如果读取音频数据没有出错，就将数据写入到文件
                if (AudioRecord.ERROR_INVALID_OPERATION != read) {
                    try {
                        mFos.write(data);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * @param type 1.ImageView 绘制图片
     *             2.SurfaceView 绘制图片
     *             3.自定义 View 绘制图片
     */
    private void showImage(int type) {
        switch (type) {
            case 1:
                showImageByImageView();
                break;
            case 2:
                showImageBySurfaceView();
                break;
            case 3:
                showImageViewByCustomView();
                break;
            default:
                break;
        }
    }

    private void showImageByImageView() {
        Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + File.separator + "Download"
                + File.separator + "reba.jpg");
        ImageView imageView = new ImageView(this);
        imageView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        imageView.setImageBitmap(bitmap);
        mRootContainer.addView(imageView);
    }

    private void showImageBySurfaceView() {
        SurfaceView surfaceView = new SurfaceView(this);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                if (surfaceView == null) {
                    return;
                }
                Paint paint = new Paint();
                paint.setStyle(Paint.Style.STROKE);
                paint.setAntiAlias(true);
                Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + File.separator + "Download" + File.separator + "reba.jpg");
                //锁定surfaceView 的画布
                Canvas canvas = holder.lockCanvas();
                canvas.drawRGB(255, 255, 255);
                //执行绘制操作
                canvas.drawBitmap(bitmap, 0, 0, paint);
                //解除锁定并显示在界面上
                holder.unlockCanvasAndPost(canvas);
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
        surfaceView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mRootContainer.addView(surfaceView);
    }

    private void showImageViewByCustomView() {
        CustomImageView customImageView = new CustomImageView(this);
        customImageView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mRootContainer.addView(customImageView);
    }

    @OnClick({R.id.btn_texture_camera,R.id.btn_surfaceView_camera, R.id.btn_record, R.id.btn_stop, R.id.btn_pcm_convert})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_record:
                new RxPermissions(this).request(Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(aBoolean -> {
                    LogUtils.iTag("record", aBoolean);
                    if (aBoolean) {
                        record();
                    }
                });
                break;
            case R.id.btn_stop:
                stopRecord();
                break;
            case R.id.btn_pcm_convert:
                String pcmFileName = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Record" + File.separator + "test.pcm";
                String wavFileName = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Record" + File.separator + "test.wav";
                final File pcmFile = new File(pcmFileName);
                final File wavFile = new File(wavFileName);
                if (!wavFile.getParentFile().exists()) {
                    wavFile.mkdirs();
                }
                if (wavFile.exists()) {
                    wavFile.delete();
                }
                PcmToWavUtil pcmToWavUtil = new PcmToWavUtil(GlobalConfig.SAMPLE_RATE_INHZ, GlobalConfig.CHANNEL_CONFIG, GlobalConfig.AUDIO_FORMAT);
                pcmToWavUtil.pcmToWav(pcmFileName, wavFileName);
                break;
            case R.id.btn_surfaceView_camera:
                new RxPermissions(this)
                        .request(Manifest.permission.CAMERA)
                        .subscribe(aBoolean -> {
                            if (aBoolean) {

                                preCameraBySurfaceView();
                            }
                        });
                break;
            case R.id.btn_texture_camera:
                new RxPermissions(this)
                        .request(Manifest.permission.CAMERA)
                        .subscribe(aBoolean -> {
                            if (aBoolean) {
                                preCameraByTextureView();
                            }
                        });
                break;
            default:
                break;
        }
    }

    private void preCameraByTextureView() {

        TextureView textureView=new TextureView(this);
        textureView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        android.hardware.Camera camera = null;
        camera= android.hardware.Camera.open();
        camera.setDisplayOrientation(90);
        android.hardware.Camera finalCamera = camera;
        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
                try {
                    finalCamera.setPreviewTexture(surfaceTexture);
                    finalCamera.startPreview();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                finalCamera.release();
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {

            }
        });
        mRootContainer.addView(textureView);
    }

    private void preCameraBySurfaceView() {
        SurfaceView surfaceView = new SurfaceView(this);
        surfaceView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        android.hardware.Camera camera = null;
        camera= android.hardware.Camera.open();
        camera.setDisplayOrientation(90);
        android.hardware.Camera finalCamera = camera;
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                try {
                    finalCamera.setPreviewDisplay(holder);
                    finalCamera.startPreview();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                finalCamera.release();
            }
        });
        mRootContainer.addView(surfaceView);
    }

    public void stopRecord() {
        ToastUtils.showShort("停止录音...");
        if (mFos != null) {
            try {
                mFos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != mAudioRecord) {
            mAudioRecord.stop();
            mAudioRecord.release();
            mAudioRecord = null;
            isRecord = false;
        }
    }
}
